Secure Computing - IrisCTF 2024
フラグチェッカー問
ここで8つのフィルターを設定していることに注意
code:c
void _INIT_0(void)
{
long lVar1;
long in_FS_OFFSET;
undefined8 local_40;
long local_30;
local_30 = *(long *)(in_FS_OFFSET + 0x28);
lVar1 = ptrace(PTRACE_TRACEME,0);
if (-1 < lVar1) {
lVar1 = 0;
prctl(0x26,1,0,0,0);
do {
local_480 = (undefined2)*(undefined8 *)((long)&LONG_00302020 + lVar1); local_40 = *(undefined8 *)((long)&PTR_DAT_0033d560 + lVar1);
lVar1 = lVar1 + 8;
syscall(0x13d,1,0,local_48);
} while (lVar1 != 0x40);
}
if (local_30 == *(long *)(in_FS_OFFSET + 0x28)) {
return;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
seccomp-tools dump -l 8 ./chalのようにするとまとめてできる
あとはフィルターに合致するようにフラグを求めるプログラムをz3で書くだけ code: solve.py
import re
from z3 import *
s = Solver()
def expr(x: str):
if x == 'sys_number':
return 0x1337
elif x == 'arch':
return 0xc000003e
elif x == 'A':
return A
elif x == 'X':
return X
elif x.startswith('mem['):
elif x.startswith('args['):
elif x.startswith('0x'):
return int(x, 16)
else:
return int(x, 10)
def u32(x):
return x & 0xffffffff
for i in range(1, 9):
A = 0
X = 0
with open(f'seccomp-{i}.dump', 'r') as f:
f.readline()
f.readline()
for line in f:
if m := re.match(r'if \(A == (.+)\) goto \d+', line):
s.add(A == expr(m.group(1)))
elif m := re.match(r'if \(A != (.+)\) goto \d+', line):
s.add(A == expr(m.group(1)))
elif m := re.match(r'return (.+)', line):
pass
elif m := re.match(r'A \+= (.+)', line):
A = u32(A + expr(m.group(1)))
elif m := re.match(r'A -= (.+)', line):
A = u32(A - expr(m.group(1)))
elif m := re.match(r'A \*= (.+)', line):
A = u32(A * expr(m.group(1)))
elif m := re.match(r'A &= (.+)', line):
A &= expr(m.group(1))
elif m := re.match(r'A \|= (.+)', line):
A |= expr(m.group(1))
elif m := re.match(r'A \^= (.+)', line):
A ^= expr(m.group(1))
elif m := re.match(r'mem\[(0-9+)\] = (.+)', line): elif m := re.match(r'X = (.+)', line):
X = u32(expr(m.group(1)))
elif m := re.match(r'A = args\[(0-9+)\] >> 32', line): elif m := re.match(r'A = (.+)', line):
A = u32(expr(m.group(1)))
else:
print(line)
exit()
if s.check() == unsat:
print('unsat :(')
exit()
print('sat :)')
m = s.model()
flag = ''.join([int.to_bytes(marg.as_long(), 8, 'little').decode() for arg in args]) print(f'irisctf{{{flag}}}')
seccompのレジスタは32bitなので注意